package com.uduemc.biso.node.web.component.html;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

import org.apache.velocity.Template;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;

import com.uduemc.biso.node.core.common.entities.SiteNavigationSystemData;
import com.uduemc.biso.node.core.common.siteconfig.SiteMenuConfig;
import com.uduemc.biso.node.core.entities.SArticleSlug;
import com.uduemc.biso.node.core.entities.SCategories;
import com.uduemc.biso.node.core.entities.SPage;
import com.uduemc.biso.node.core.entities.SSystem;
import com.uduemc.biso.node.web.component.SiteUrlComponent;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.StrUtil;

@Component
public class HNavigationUdin {

	private static String name = "navigation";

	@Autowired
	private BasicUdin basicUdin;

	@Autowired
	private SiteUrlComponent siteUrlComponent;

	// 是否通过 surface 的方式渲染
	static boolean surface = false;

	public StringBuilder html(long pageId, List<SPage> pageData, SiteMenuConfig siteMenuConfig, List<SiteNavigationSystemData> listSiteNavigationSystemData,
			boolean tmenu) {

		if (surface) {
			return surfaceRender(pageId, pageData, siteMenuConfig, listSiteNavigationSystemData, tmenu);
		}

		return render(pageId, pageData, siteMenuConfig, listSiteNavigationSystemData, tmenu);

	}

	public StringBuilder surfaceRender(long pageId, List<SPage> pageData, SiteMenuConfig siteMenuConfig,
			List<SiteNavigationSystemData> listSiteNavigationSystemData, boolean tmenu) {
		StringBuilder result = new StringBuilder();

		// 制作生成 页面的导航菜单
		List<PageData> listPageData = PageData.getListPageData(pageData);
		// 当前页面的 pageId 数据链表
		List<Long> activePageId = getActivePageId(pageId, pageData);

		int index = 0;
		// 三层嵌套
		int maxIndex = siteMenuConfig.getMaxIndex();

		getHtmlByData(result, activePageId, listPageData, listSiteNavigationSystemData, index, 0L, maxIndex, tmenu);

		if (tmenu) {
			return new StringBuilder("<!-- navigation --><div class=\"navigation-render-tmenu\" hidden>" + result + "</div>");
		} else {
			return new StringBuilder("<!-- navigation --><div class=\"navigation-render\" hidden>" + result + "</div>");
		}
	}

	public StringBuilder render(long pageId, List<SPage> pageData, SiteMenuConfig siteMenuConfig, List<SiteNavigationSystemData> listSiteNavigationSystemData,
			boolean tmenu) {
		StringBuilder result = new StringBuilder("<!-- navigation -->");

		String menuCurStyle = menuCurStyle(siteMenuConfig);
		String menuStyle = menuStyle(siteMenuConfig);
		int subFontWrap = siteMenuConfig.getSubFontWrap();

		// style 部分后天添加对菜单的样式调整功能
		StringBuilder style = new StringBuilder();
		if (StrUtil.isNotBlank(menuStyle)) {
			style.append(".w-nav-pcs .nav_inner > li > a, .w-nav-pcs .nav_inner > li > .li-parent-div > a{" + menuStyle + "}");
		}
		if (StrUtil.isNotBlank(menuCurStyle)) {
			style.append(
					".w-nav-pcs .nav_inner > li:hover > a, .w-nav-pcs .nav_inner > li:hover > .li-parent-div > a, .w-nav-pcs .nav_inner > li.active > a, .w-nav-pcs .nav_inner > li.active > .li-parent-div > a{"
							+ menuCurStyle + "}");
		}
		if (subFontWrap == 1) {
			style.append(
					".w-nav-pcs .nav_inner > li > .submenu{ left:0; margin-left:0;}.w-nav-pcs .submenu li{width:auto; white-space:nowrap;min-width:170px;} .w-nav-pcs .submenu li a{ text-align:left;}.w-nav-pcs .submenu li .submenu{ left:100%;}");
		}
		if (StrUtil.isNotBlank(style)) {
			result.append("<style type=\"text/css\">");
			result.append(style);
			result.append("</style>");
		}

		// 制作生成 页面的导航菜单
		List<PageData> listPageData = PageData.getListPageData(pageData);
		// 当前页面的 pageId 数据链表
		List<Long> activePageId = getActivePageId(pageId, pageData);

		int index = 0;
		// 三层嵌套
		int maxIndex = siteMenuConfig.getMaxIndex();

		getHtmlByData(result, activePageId, listPageData, listSiteNavigationSystemData, index, 0L, maxIndex, tmenu);

		return result;
	}

	protected void getHtmlByData(StringBuilder stringBuilder, List<Long> actionPageId, List<PageData> listPageData,
			List<SiteNavigationSystemData> listSiteNavigationSystemData, int index, long parentId, int maxIndex, boolean tmenu) {
		if (index > maxIndex) {
			return;
		}

		String gWebUlMenu = "";
		if (tmenu) {
			gWebUlMenu = "id=\"g-web-ul-menu\" style=\"display:none;\"";
		}
		if (index == 0) {
			stringBuilder.append("<div class=\"w-nav\"><div class=\"w-nav-in\"><ul class=\"nav_inner clearfix\" " + gWebUlMenu + ">");
		} else if (index == 1 || index == 2) {
			stringBuilder.append("<div class=\"submenu\">");
			stringBuilder.append("<div class=\"back-div\"><i class=\"fa fa-angle-left\"></i><span><<</span></div>");
			stringBuilder.append("<ul>");
		}

		stringBuilder.append(
				"<script type=\"text/javascript\">$(function(){if($('.mobile-nav-toggle').is(':hidden')){$('.w-nav').addClass('w-nav-pcs')}$(window).on('resize',function(){if($('.mobile-nav-toggle').is(':hidden')){$('.w-nav').addClass('w-nav-pcs')}else{$('.w-nav').removeClass('w-nav-pcs')}})})</script>");

		List<SPage> listSPage = getPageDataByParentId(listPageData, parentId);
		Iterator<SPage> iterator = listSPage.iterator();
		while (iterator.hasNext()) {
			SPage sPage = iterator.next();
			Long systemId = sPage.getSystemId();
			// 是否存在分类或者短标题数据
			SiteNavigationSystemData siteNavigationSystemData = null;
			// 是否存在 children
			boolean children = false;
			if (systemId == null || systemId.longValue() == 0) {
				List<SPage> childrenListSPage = getPageDataByParentId(listPageData, sPage.getId());
				if (!CollectionUtils.isEmpty(childrenListSPage)) {
					children = true;
				}
			} else {
				if (CollectionUtil.isEmpty(listSiteNavigationSystemData)) {
					continue;
				}
				Iterator<SiteNavigationSystemData> iteratorSiteNavigationSystemData = listSiteNavigationSystemData.iterator();
				while (iteratorSiteNavigationSystemData.hasNext()) {
					SiteNavigationSystemData next = iteratorSiteNavigationSystemData.next();
					if (next.getSystem() != null && next.getSystem().getId() != null
							&& next.getSystem().getId().longValue() == sPage.getSystemId().longValue()) {
						siteNavigationSystemData = next;
					}
				}
				if (siteNavigationSystemData != null && (!CollectionUtils.isEmpty(siteNavigationSystemData.getListSCategories())
						|| !CollectionUtils.isEmpty(siteNavigationSystemData.getListSArticleSlug()))) {
					children = true;
				}
			}

			// 是否当前页面
			if (isActive(sPage, actionPageId)) {
				stringBuilder.append("<li class=\"active\">");
			} else {
				stringBuilder.append("<li>");
			}

			if (!children || index == maxIndex) {
				if (index == 0) {
					String navigationATagBySPage = siteUrlComponent.getNavigationATagBySPage(sPage);
					stringBuilder.append(navigationATagBySPage);
					stringBuilder.append("<i class=\"nav_simpline_cur\"></i>");
				} else if (index == 1 || index == 2) {
					String navigationATagBySPage = siteUrlComponent.getNavigationATagBySPage(sPage);
					stringBuilder.append(navigationATagBySPage);
				}
			} else {
				String navigationATagBySPage = siteUrlComponent.getNavigationATagBySPage(sPage, "<i class=\"fa fa-plus\"></i>");
				stringBuilder.append("<div class=\"li-parent-div li-parentOne-div\">");
				stringBuilder.append(navigationATagBySPage);
				stringBuilder.append("</div>");
				if (index == 0) {
					stringBuilder.append("<i class=\"nav_simpline_cur\"></i>");
				}

				if (systemId == null || systemId.longValue() == 0) {
					getHtmlByData(stringBuilder, actionPageId, listPageData, listSiteNavigationSystemData, index + 1, sPage.getId(), maxIndex, tmenu);
				} else {
					// 系统页面
					getHtmlByData(stringBuilder, sPage, siteNavigationSystemData, index + 1, maxIndex);
				}
			}

			// 结束 是否当前页面
			stringBuilder.append("</li>");
		}

		if (index == 0) {
			stringBuilder.append("<div class=\"nav_moveBox\"></div></ul></div></div>");
		} else if (index == 1 || index == 2) {
			stringBuilder.append("</ul></div>");
		}

	}

	/**
	 * 短标题菜单制作
	 * 
	 * @param stringBuilder
	 * @param sPage
	 * @param siteNavigationSystemData
	 * @param index
	 * @param maxIndex
	 */
	protected void getHtmlByData(StringBuilder stringBuilder, SPage sPage, SiteNavigationSystemData siteNavigationSystemData, int index, int maxIndex) {
		if (index > maxIndex) {
			return;
		}
		SSystem system = siteNavigationSystemData.getSystem();
		if (system.getSystemTypeId().longValue() == 2) {
			// 取短标题
			List<SArticleSlug> listSArticleSlug = siteNavigationSystemData.getListSArticleSlug();
			if (CollectionUtils.isEmpty(listSArticleSlug)) {
				return;
			}
			List<SArticleSlugData> listSArticleSlugData = SArticleSlugData.getListSArticleSlugData(listSArticleSlug);
			getHtmlByDataSArticleSlugData(stringBuilder, sPage, listSArticleSlugData, index, 0L, maxIndex);
		} else {
			// 取分类
			List<SCategories> listSCategories = siteNavigationSystemData.getListSCategories();
			if (CollectionUtils.isEmpty(listSCategories)) {
				return;
			}
			List<SCategoryData> listSCategoryData = SCategoryData.getListSCategoryData(listSCategories);

			getHtmlByData(stringBuilder, sPage, listSCategoryData, index, 0L, maxIndex);
		}
	}

	/**
	 * 短标题菜单制作
	 * 
	 * @param stringBuilder
	 * @param sPage
	 * @param listSCategoryData
	 * @param index
	 */
	protected void getHtmlByDataSArticleSlugData(StringBuilder stringBuilder, SPage sPage, List<SArticleSlugData> listSArticleSlugData, int index,
			long parentId, int maxIndex) {
		if (index > maxIndex) {
			return;
		}
		SArticleSlugData sArticleSlugData = null;
		Iterator<SArticleSlugData> iterator = listSArticleSlugData.iterator();
		while (iterator.hasNext()) {
			SArticleSlugData next = iterator.next();
			if (next.parendId == parentId) {
				sArticleSlugData = next;
			}
		}
		if (sArticleSlugData == null) {
			return;
		}
		stringBuilder.append("<div class=\"submenu\">");
		stringBuilder.append("<div class=\"back-div\"><i class=\"fa fa-angle-left\"></i><span><<</span></div>");
		stringBuilder.append("<ul>");
		List<SArticleSlug> listSArticleSlug = sArticleSlugData.data;
		listSArticleSlug.forEach(item -> {
			// 是否存在children
			Long id = item.getId();
			SArticleSlugData sArticleSlugDataChildren = null;
			Iterator<SArticleSlugData> iteratorChildren = listSArticleSlugData.iterator();
			while (iteratorChildren.hasNext()) {
				SArticleSlugData next = iteratorChildren.next();
				if (next.parendId == id.longValue()) {
					sArticleSlugDataChildren = next;
				}
			}
			if (sArticleSlugDataChildren == null || index == maxIndex) {
				// 不存在子节点
				String navigationATagBySPage = siteUrlComponent.getNavigationATagBySPage(sPage, item);
				stringBuilder.append("<li>" + navigationATagBySPage + "</li>");
			} else {
				// 存在子节点
				stringBuilder.append("<li>");
				stringBuilder.append("<div class=\"li-parent-div li-parentOne-div\">");
				String navigationATagBySPage = siteUrlComponent.getNavigationATagBySPage(sPage, item, "<i class=\"fa fa-plus\"></i>");
				stringBuilder.append(navigationATagBySPage);
				stringBuilder.append("</div>");
				getHtmlByDataSArticleSlugData(stringBuilder, sPage, listSArticleSlugData, index + 1, id, maxIndex);
				stringBuilder.append("</li>");

			}
		});
		stringBuilder.append("</ul></div>");
	}

	/**
	 * 分类菜单制作
	 * 
	 * @param stringBuilder
	 * @param sPage
	 * @param listSCategoryData
	 * @param index
	 */
	protected void getHtmlByData(StringBuilder stringBuilder, SPage sPage, List<SCategoryData> listSCategoryData, int index, long parentId, int maxIndex) {
		if (index > maxIndex) {
			return;
		}
		SCategoryData sCategoryData = null;
		Iterator<SCategoryData> iterator = listSCategoryData.iterator();
		while (iterator.hasNext()) {
			SCategoryData next = iterator.next();
			if (next.parendId == parentId) {
				sCategoryData = next;
			}
		}
		if (sCategoryData == null) {
			return;
		}

		stringBuilder.append("<div class=\"submenu\">");
		stringBuilder.append("<div class=\"back-div\"><i class=\"fa fa-angle-left\"></i><span><<</span></div>");
		stringBuilder.append("<ul>");
		List<SCategories> listSCategories = sCategoryData.data;
		listSCategories.forEach(item -> {
			// 是否存在children
			Long id = item.getId();
			SCategoryData sCategoryDataChildren = null;
			Iterator<SCategoryData> iteratorChildren = listSCategoryData.iterator();
			while (iteratorChildren.hasNext()) {
				SCategoryData next = iteratorChildren.next();
				if (next.parendId == id.longValue()) {
					sCategoryDataChildren = next;
				}
			}
			if (sCategoryDataChildren == null || index == maxIndex) {
				// 不存在子节点
				String navigationATagBySPage = siteUrlComponent.getNavigationATagBySPage(sPage, item);
				stringBuilder.append("<li>" + navigationATagBySPage + "</li>");
			} else {
				// 存在子节点
				stringBuilder.append("<li>");
				stringBuilder.append("<div class=\"li-parent-div li-parentOne-div\">");
				String navigationATagBySPage = siteUrlComponent.getNavigationATagBySPage(sPage, item, "<i class=\"fa fa-plus\"></i>");
				stringBuilder.append(navigationATagBySPage);
				stringBuilder.append("</div>");

				getHtmlByData(stringBuilder, sPage, listSCategoryData, index + 1, id, maxIndex);

				stringBuilder.append("</li>");
			}
		});
		stringBuilder.append("</ul></div>");
	}

	protected static List<SPage> getPageDataByParentId(List<PageData> listPageData, long parentId) {
		Iterator<PageData> iterator = listPageData.iterator();
		while (iterator.hasNext()) {
			PageData next = iterator.next();
			if (next.parendId == parentId) {
				return next.page;
			}
		}
		return null;
	}

	protected static List<Long> getActivePageId(long pageId, List<SPage> pageData) {
		List<Long> result = new ArrayList<>();
		result.add(pageId);

		long id = pageId;
		while (true) {

			Long parentId = getParentId(id, pageData);
			if (parentId == null || parentId.longValue() == 0) {
				break;
			}

			result.add(parentId);

			id = parentId.longValue();
		}

		return result;
	}

	protected static Long getParentId(long pageId, List<SPage> pageData) {
		Iterator<SPage> iterator = pageData.iterator();
		while (iterator.hasNext()) {
			SPage next = iterator.next();
			if (next.getId().longValue() == pageId) {
				return next.getParentId();
			}
		}
		return null;
	}

	protected static boolean isActive(SPage sPage, List<Long> actionPageId) {
		for (Long activeId : actionPageId) {
			if (sPage.getId().longValue() == activeId.longValue()) {
				return true;
			}
		}
		return false;
	}

	public Template getTemplate(String theme) {
		return basicUdin.getTemplate(name, theme);
	}

	private static class PageData {

		@Override
		public String toString() {
			return "PageData [parendId=" + parendId + ", page=" + page + "]";
		}

		@SuppressWarnings("unused")
		public long parendId;
		public List<SPage> page;

		public static List<PageData> getListPageData(List<SPage> pageData) {
			// 定义列表数据
			List<PageData> list = new ArrayList<HNavigationUdin.PageData>();
			Iterator<SPage> iterator = pageData.iterator();
			while (iterator.hasNext()) {
				SPage next = iterator.next();
				// 找到存在的item
				boolean in = false;
				PageData item = null;
				for (PageData pData : list) {
					if (pData.parendId == next.getParentId().longValue()) {
						item = pData;
						in = true;
						break;
					}
				}

				if (item == null) {
					item = new PageData();
					item.parendId = next.getParentId();
					item.page = new ArrayList<>();
				}

				item.page.add(next);

				if (!in) {
					list.add(item);
				}
			}

			return list;
		}
	}

	private static class SArticleSlugData {

		@SuppressWarnings("unused")
		public long parendId;
		public List<SArticleSlug> data;

		public static List<SArticleSlugData> getListSArticleSlugData(List<SArticleSlug> data) {
			// 定义列表数据
			List<SArticleSlugData> list = new ArrayList<HNavigationUdin.SArticleSlugData>();
			Iterator<SArticleSlug> iterator = data.iterator();
			while (iterator.hasNext()) {
				SArticleSlug next = iterator.next();
				// 找到存在的item
				boolean in = false;
				SArticleSlugData item = null;
				for (SArticleSlugData pData : list) {
					if (pData.parendId == next.getParentId().longValue()) {
						item = pData;
						in = true;
						break;
					}
				}

				if (item == null) {
					item = new SArticleSlugData();
					item.parendId = next.getParentId();
					item.data = new ArrayList<>();
				}

				item.data.add(next);

				if (!in) {
					list.add(item);
				}
			}

			return list;
		}
	}

	private static class SCategoryData {

		@SuppressWarnings("unused")
		public long parendId;
		public List<SCategories> data;

		public static List<SCategoryData> getListSCategoryData(List<SCategories> data) {
			// 定义列表数据
			List<SCategoryData> list = new ArrayList<HNavigationUdin.SCategoryData>();
			Iterator<SCategories> iterator = data.iterator();
			while (iterator.hasNext()) {
				SCategories next = iterator.next();
				// 找到存在的item
				boolean in = false;
				SCategoryData item = null;
				for (SCategoryData pData : list) {
					if (pData.parendId == next.getParentId().longValue()) {
						item = pData;
						in = true;
						break;
					}
				}

				if (item == null) {
					item = new SCategoryData();
					item.parendId = next.getParentId();
					item.data = new ArrayList<>();
				}

				item.data.add(next);

				if (!in) {
					list.add(item);
				}
			}

			return list;
		}
	}

	protected static String menuCurStyle(SiteMenuConfig siteMenuConfig) {
		StringBuilder stringBuilder = new StringBuilder();
		String topSelectionColor = siteMenuConfig.getTopSelectionColor();
		if (StrUtil.isNotBlank(topSelectionColor)) {
			stringBuilder.append("color: " + topSelectionColor + ";");
		}
		return stringBuilder.toString();
	}

	protected static String menuStyle(SiteMenuConfig siteMenuConfig) {
		StringBuilder stringBuilder = new StringBuilder();
		String topFontColor = siteMenuConfig.getTopFontColor();
		String topFontFamily = siteMenuConfig.getTopFontFamily();
		String topFontSize = siteMenuConfig.getTopFontSize();
		String topFontStyle = siteMenuConfig.getTopFontStyle();
		if (StrUtil.isNotBlank(topFontColor)) {
			stringBuilder.append("color: " + topFontColor + ";");
		}
		if (StrUtil.isNotBlank(topFontFamily)) {
			stringBuilder.append("font-family: " + topFontFamily + ";");
		}
		if (StrUtil.isNotBlank(topFontSize)) {
			stringBuilder.append("font-size: " + topFontSize + ";");
		}
		if (StrUtil.isNotBlank(topFontStyle)) {
			stringBuilder.append("font-weight: " + topFontStyle + ";");
		}
		return stringBuilder.toString();
	}
}
